<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Notification extends Model
{
    use HasFactory;

    protected $fillable = [
        'type',
        'title',
        'content',
        'data',
        'level',
        'status',
        'sender_id',
        'recipient_id',
        'read_at',
        'expires_at',
    ];

    protected $casts = [
        'data' => 'array',
        'read_at' => 'datetime',
        'expires_at' => 'datetime',
    ];

    /**
     * 关联发送者
     */
    public function sender(): BelongsTo
    {
        return $this->belongsTo(User::class, 'sender_id');
    }

    /**
     * 关联接收者
     */
    public function recipient(): BelongsTo
    {
        return $this->belongsTo(User::class, 'recipient_id');
    }

    /**
     * 检查通知是否已读
     */
    public function isRead(): bool
    {
        return $this->status === 'read';
    }

    /**
     * 检查通知是否未读
     */
    public function isUnread(): bool
    {
        return $this->status === 'unread';
    }

    /**
     * 检查通知是否已归档
     */
    public function isArchived(): bool
    {
        return $this->status === 'archived';
    }

    /**
     * 检查通知是否过期
     */
    public function isExpired(): bool
    {
        return $this->expires_at && $this->expires_at->isPast();
    }

    /**
     * 标记为已读
     */
    public function markAsRead(): void
    {
        $this->update([
            'status' => 'read',
            'read_at' => now(),
        ]);
    }

    /**
     * 标记为未读
     */
    public function markAsUnread(): void
    {
        $this->update([
            'status' => 'unread',
            'read_at' => null,
        ]);
    }

    /**
     * 归档通知
     */
    public function archive(): void
    {
        $this->update(['status' => 'archived']);
    }

    /**
     * 获取通知级别标签
     */
    public function getLevelLabelAttribute(): string
    {
        $levelLabels = [
            'info' => '信息',
            'warning' => '警告',
            'error' => '错误',
            'success' => '成功',
        ];

        return $levelLabels[$this->level] ?? $this->level;
    }

    /**
     * 获取状态标签
     */
    public function getStatusLabelAttribute(): string
    {
        $statusLabels = [
            'unread' => '未读',
            'read' => '已读',
            'archived' => '已归档',
        ];

        return $statusLabels[$this->status] ?? $this->status;
    }

    /**
     * 获取通知类型标签
     */
    public function getTypeLabelAttribute(): string
    {
        $typeLabels = [
            'system' => '系统通知',
            'business' => '业务通知',
            'personal' => '个人消息',
            'approval' => '审批通知',
            'reminder' => '提醒通知',
        ];

        return $typeLabels[$this->type] ?? $this->type;
    }

    /**
     * 获取通知级别颜色
     */
    public function getLevelColorAttribute(): string
    {
        $levelColors = [
            'info' => '#17A2B8',
            'warning' => '#FFC107',
            'error' => '#DC3545',
            'success' => '#28A745',
        ];

        return $levelColors[$this->level] ?? '#6C757D';
    }

    /**
     * 获取通知级别图标
     */
    public function getLevelIconAttribute(): string
    {
        $levelIcons = [
            'info' => 'info-circle',
            'warning' => 'exclamation-triangle',
            'error' => 'times-circle',
            'success' => 'check-circle',
        ];

        return $levelIcons[$this->level] ?? 'bell';
    }

    /**
     * 检查通知是否紧急
     */
    public function isUrgent(): bool
    {
        return in_array($this->level, ['error', 'warning']);
    }

    /**
     * 获取用户未读通知数量
     */
    public static function getUnreadCount(int $userId): int
    {
        return static::where('recipient_id', $userId)
            ->where('status', 'unread')
            ->where(function ($query) {
                $query->whereNull('expires_at')
                    ->orWhere('expires_at', '>', now());
            })
            ->count();
    }

    /**
     * 获取用户通知列表
     */
    public static function getUserNotifications(int $userId, int $limit = 20)
    {
        return static::where('recipient_id', $userId)
            ->where(function ($query) {
                $query->whereNull('expires_at')
                    ->orWhere('expires_at', '>', now());
            })
            ->orderBy('created_at', 'desc')
            ->limit($limit)
            ->get();
    }
}
